package fms.controller;

import fms.dao.CptInfoService;
import fms.dao.CptSendService;
import fms.dao.PlanCptWdService;
import fms.model.CptInfo;
import fms.model.CptSend;
import fms.model.PlanCptWd;
import fms.model.PlanFlightInfoBuff;
import fms.util.*;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <P>FileName: SABREFlyPlanParseController.java
 *
 *         <P>Description: 解析东航飞行计划服务
 *         <P>Version: v1.0
 *         <P>History:
 */
public class SABREFlyPlanParseController implements IFlyPlanParseController {

    private Logger logger = Logger.getLogger(SABREFlyPlanParseController.class);

    // 存入CPT_INFO\PLAN_CPT_WD表的记录列表数据
    private List cptInfoList = new ArrayList();
    private List planCptWdList = new ArrayList();

    private JetplanParseRuleVO paramVO = new JetplanParseRuleVO();
    private Map<String, String> mapAirlinesCodes = new HashMap<String, String>();

    // 提供数据库交互服务的对象
    private CptInfoService cptInfoService = null;
    private PlanCptWdService planCptWdService = null;
    private CptSendService cptSendService = null;
    // 航班号、起飞机场、降落机场
//    private final String regexFlightnumDepArr = "FLGT NO: (.+?)\\s+?ROUTE: (.+?)-(.+?)\\s+?[\\s\\S]*";
    //group:1.flightNo. 2. Date  3. dep 4. arr 5.aircraft 6.tailNo. 7.planid 8. grib 9.avgwind 10.td
    private final String regexFlightnumDepArr = "(.+?)/([0-9]{2}[A-Z]{3}[0-9]{2})\\s+?([A-Z]{4})/([A-Z]{4})\\s+?(\\w+)/(\\w+)\\s+?(.+?)\\s+?([0-9]{4})\\s+?(\\w+)/(\\w+)";
    // 记录正则regexFlightnumDepArr是否匹配成功
    private boolean bFlightnumDepArr = false;

    // 机尾号
//    private final String regexAircraftid = "AC REG.: (.+?)\\s+?.+?";
    // 记录正则regexAircraftid是否匹配成功
    private boolean bAircraftid = false;

    // 航路点经纬度
//    private final String regexCpt = "(\\w+)/(\\w+)/\\s+?([0-9]*)\\s+?([0-9]*)\\s+?([0-9]*)\\s+?....\\s+?([0-9]*)\\s+?([0-9]*)/\\s+?([0-9]*)";
    private final String regexCpt = "(.*?)/(.*?)\\s+?(/*)(.*?)";

    // 记录正则regexCpt是否匹配成功
    private boolean bCpt = false;
    //    private final String regexLatLon = "(.*?)\\s+?/([N|S][0-9]{2})\\s+?(^\\d+(\\.\\d+)?$)\\s+?([E|W][0-9]{2})\\s+?(^\\d+(\\.\\d+)?$)(.*?)";
    private final String regexLatLon = "(.*?)\\s+?/(.*?)\\s+?(.*?)\\s+?(.*?)\\s+?(.*?)\\s+?(.*?)";

    private boolean bAlt = false;

    //航路点表头
    private final String regexWindHeader="POINT\\s+?FL([0-9]*)\\s+?FL([0-9]*)FL\\s+?1XLOWER\\s+?FL\\s+?PLANNED\\s+?FL\\s+?1XHIGHER";

    // 航路点位置及个高度层风速风向
    private final String regexCptPosWindFuzzy = "(\\w+)\\s+?([0-9]{6})([P|M][0-9]{3})\\s+?([0-9]{6})([P|M][0-9]{3})\\s+?([0-9]{3})\\s+?([0-9]{6})([P|M][0-9]{3})" +
            "\\s+?([0-9]{3})\\s+?([0-9]{6})([P|M][0-9]{3})\\s+?([0-9]{3})\\s+?([0-9]{6})([P|M][0-9]{3})";

    // 为了过滤出“经度、纬度、风速、风向”位数过多过少不合法情况，进行两次匹配规则
    // 航路点位置及个高度层风速风向（二轮：精确匹配）
//    private final String regexCptPosWindExact = "\\d{2}\\s+?(\\w+?)\\s+?([NS]\\d{5})\\s+?([EW]\\d}{6})\\s+?(\\w{3}/\\w{3})\\s+?" +
//            "(\\w{3}/\\w{3})\\s+?(\\w{3}/\\w{3})\\s+?(\\w{3}/\\w{3})\\s+?(\\w{3}/\\w{3})\\s+?(\\w{3}/\\w{3})";

    // 记录正则regexCptPosWind是否匹配成功
    private boolean bCptPosWind = false;

    // 航班计划时间
    private final String regexPlanTime = "[\\s\\S]*(\\d{4}/\\d{1,2}/\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2})";
    // 记录正则regexPlanTime是否匹配成功
    private boolean bPlanTime = false;

    // 飞行计划中的高度层数
    public static final int NumAlt = 6;

    // 飞行计划字符串编码方式
    private final String StrEncoding =  "UTF-8";

    private HashMap cptLon=new HashMap();
    private HashMap cptLat=new HashMap();

    private Calendar cal=Calendar.getInstance();
    private CptSend cptSend;

    private SimpleDateFormat sdf1=new SimpleDateFormat("HHmm");
    private SimpleDateFormat sdf2=new SimpleDateFormat("yyyyMMdd");
    private SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmm");

//    int maxFL=0;
//    int minFL=0;
    private String depDate="";
    private String fileName="";

    // 读取配置文件，加载解析TXT型飞行计划所需的参数信息
    public SABREFlyPlanParseController(String fileName) {

        cptInfoService = ConfUtil.getSingletonApplicationContextDao().getBean("cptInfoService", CptInfoService.class);
        planCptWdService = ConfUtil.getSingletonApplicationContextDao().getBean("planCptWdService", PlanCptWdService.class);
        cptSendService=ConfUtil.getSingletonApplicationContextDao().getBean("cptSendService",CptSendService.class);
        this.fileName=fileName;
        File fParseRule = null;
        fParseRule = new java.io.File(ConfUtil.props.getProperty("parseRuleFilePath"));
        final SAXReader reader = new SAXReader();
        try {
            logger.info("（TXT飞行计划解析）航空公司三字码和二字码对照表加载中！");
            final Document paraseRulenDoc = reader.read(fParseRule);
            List airlineCodeList = paraseRulenDoc.selectNodes("/FPLParseRules/TxtplanParseRule/AirlinesFlags/AirlineCode");
            Iterator it = airlineCodeList.iterator();
            while (it.hasNext()) {
                Element airlinesCode = (Element) it.next();
                mapAirlinesCodes.put(airlinesCode.attributeValue("id"), airlinesCode.getTextTrim());
            }
            logger.info("（TXT飞行计划解析）航空公司三字码和二字码对照表加载结束！");
        } catch (final Exception e) {
            logger.error(e.getMessage());
        }
    }

    @Override
    public boolean parseDataSource(File fDataSource) {
        return false;
    }

    /**
     * 算法细节描述：
     * 单个航路点的某一个高度层的风速、风向不和法（位数、内容），则丢弃该高度层的风速、风向信息；
     * 航路点经度纬度不合法（位数、内容），则丢弃整个航路点信息；
     *
     * 接口变更说明：
     *    由于最初开发时，使用FILE接口，反复三次打开文件，以便正则匹配出不同的数据；
     *    现在，更改成strDataSource方式后，反复三次将字符串转换为输入流
     *
     * @param strDataSource : 用于存储飞行计划全文
     */
    @Override
    public boolean parseDataSource(String strDataSource) {

        cptLon.clear();
        cptLat.clear();

        try {

            int baseStart=strDataSource.indexOf("AVGWC/TD");
            int baseStop=strDataSource.indexOf("FMS");
            if(baseStart==-1||baseStop==-1){
                logger.error("飞行计划基础信息起始或者终止标志位缺失，解析失败！");
                return false;
            }
            String baseInfo=strDataSource.substring(baseStart+10,baseStop);
            String[] baseInfos=null;
            try{
                baseInfos=baseInfo.split("\r\n");
            }
            catch(Exception e){
                logger.error("飞行计划基础信息缺失回车换行，解析失败！");
                return false;
            }
            //解析RouteLine,首先截出大致的报文范围
            int routeLineStart=strDataSource.indexOf("FMS ROUTE");
            int routeLineStop=strDataSource.indexOf(".\r\nFL PROFILE");
            String[] routeLine=null;
            if(routeLineStart==-1||routeLineStop==-1){
                logger.error("飞行计划ROUTELINE信息起始或者终止标志位缺失，预处理解析失败！");
                return false;
            }
            else{
                //精确截取内容
                String[] tmp=strDataSource.substring(routeLineStart,routeLineStop).split("\r\n");
                for(int i=1;i<tmp.length-1;i++){
                    routeLine= (String[])org.apache.commons.lang.ArrayUtils.addAll(routeLine,tmp[i].split(" "));
                }
            }

            int cptLonLatStart=strDataSource.indexOf("/FIR");

            //领航报的截至点可能是"FIRST ALTERNATE"也可能是"TAKEOFF ALTERNATE"
            //取两者的最小值
            int cptLonLatStop=-1;
            int cptLonLatStop1=strDataSource.indexOf("FIRST ALTERNATE");
            int cptLonLatStop2=strDataSource.indexOf("TAKEOFF ALTERNATE");

            if(cptLonLatStop1!=-1&&cptLonLatStop2==-1){
                cptLonLatStop=cptLonLatStop1;
            }
            else if(cptLonLatStop1==-1&&cptLonLatStop2!=-1){
                cptLonLatStop=cptLonLatStop2;
            }
            else if(cptLonLatStop1!=-1&&cptLonLatStop2!=-1){
                cptLonLatStop=cptLonLatStop1<cptLonLatStop2?cptLonLatStop1:cptLonLatStop2;
            }
            else{
                cptLonLatStop=-1;
            }
            if(cptLonLatStart==-1||cptLonLatStop==-1){
                logger.error("飞行计划领航数据起始或者终止标志位缺失，解析失败！");
                return false;
            }

            String cptLonLatInfo=strDataSource.substring(cptLonLatStart,cptLonLatStop);
            String[] cptLonLatInfos=null;
            try{
                cptLonLatInfos=cptLonLatInfo.split("-------------------------------------------------------------------\r\n");
            }
            catch(Exception e){
                logger.error("飞行计划领航数据缺失横线分隔符，解析失败！");
                return false;
            }

            int cptLevelWindStart=strDataSource.indexOf("WX PROG");
            int cptLevelWindStop=strDataSource.indexOf("XXXXXXXXXXXXXXXXXXXXXXXXX  END OF PLAN  XXXXXXXXXXXXXXXXXXXXXXXXXXX");
            if(cptLevelWindStart==-1||cptLevelWindStop==-1){
                logger.error("飞行计划航路风温摘要起始或者终止标志位缺失，解析失败！");
                return false;
            }

            String cptLevelWindInfo=strDataSource.substring(cptLevelWindStart,cptLevelWindStop);
            String[] cptLevelWindInfos=null;
            try{
                cptLevelWindInfos=cptLevelWindInfo.split("\\r\\n");
            }
            catch(Exception e){
                logger.error("飞行计划航路风温摘要缺失回车换行，解析失败！");
                return false;
            }

            // 用于缓存反复在记录中出现的字段数据
            PlanFlightInfoBuff planFlightInfoBuff = new PlanFlightInfoBuff();
            Matcher matcher1=null,matcher2=null,matcher3=null;
            Pattern pattern1= null,pattern2= null,pattern3=null;

            pattern1 = Pattern.compile(regexFlightnumDepArr);
            pattern2 = Pattern.compile(regexCpt);
            pattern3 = Pattern.compile(regexLatLon);


            /*
            一次将飞行计划中的所需信息读出，第一部分匹配航班号，起降场，结尾号，飞行计划时间（还没找到）。
            */
            boolean bFind = false;
            if(!baseInfos[0].equals("")) {
                /*第一部分匹配航班号，起降场，机尾号，飞行计划时间。
                * */
                matcher1=pattern1.matcher(baseInfos[0]);
                if (matcher1.matches()) {
//                     System.out.println(matcher1.group(1)+","+matcher1.group(2)+","+matcher1.group(3)+","+matcher1.group(4)+","+matcher1.group(5));
                    // 按行匹配航空公司标识串以确认二字码
                    for (String key : mapAirlinesCodes.keySet()) {
                        if(key.contains(matcher1.group(1).substring(0,3))){
                            planFlightInfoBuff.setAirlines(mapAirlinesCodes.get(key));
                            bFind = true;
                            break;
                        }
                    }
                    // 匹配出航班号、起飞机场、降落机场
                    if (ObjectUtil.isBlank(planFlightInfoBuff.getFlightId())) {
                        if (matcher1.group(1).trim().equals("")
                                || matcher1.group(3).trim().equals("")
                                || matcher1.group(4).trim().equals("")) {
                            logger.error("航班号、起飞机场、落地机场存在空字符串！");
                            return false;
                        }
                        else {
                            String flightID=matcher1.group(1).substring(3).trim();
                            planFlightInfoBuff.setFlightId(flightID);
                            planFlightInfoBuff.setDep(matcher1.group(3));
                            planFlightInfoBuff.setArr(matcher1.group(4));
                            bFlightnumDepArr = true;
                        }
                    }
                    // 机尾号
                    if (ObjectUtil.isBlank(planFlightInfoBuff.getAircraftId())) {
                        if (matcher1.group(6).trim().equals("")) {
                            logger.error("机尾号为空字符串！");
                            return false;
                        } else {
                            String aircraftid=matcher1.group(6);
                            if(!aircraftid.contains("-")){
                                aircraftid=aircraftid.substring(0,1)+"-"+aircraftid.substring(1);
                            }
                            planFlightInfoBuff.setAircraftId(aircraftid);
                            bAircraftid = true;
                        }
                    }
                    // 飞行计划时间
                    if (null == planFlightInfoBuff.getPlanDate()) {
                        //获取当前系统时间为计划生成时间
                        planFlightInfoBuff.setPlanDate(new Date());
                        bPlanTime = true;

//                        if (matcher1.group(2).trim().equals("")||matcher1.group(8).trim().equals("")) {
//                            logger.error("飞行计划时间为空字符串");
//                            return false;
//                         }
//                        else {
//                            //考虑跨月和跨年的情况
//                            String originDate=matcher1.group(2);
//                            String windInfoTime=matcher1.group(8);
////                            Date windInfoTime=DateUtil.StrToDateMonthAbb(originDate, SysConstants.FORMAT_DATETIME_ABBRE);
//                            int planDay=Integer.parseInt(originDate.substring(0,2));
//                            int windInfoDay=Integer.parseInt(windInfoTime.substring(0,2));
//                            Date calDate= DateUtil.StrToDateMonthAbb(originDate, "ddMMMyy");
//                            cal.setTime(calDate);
//                            if(planDay<windInfoDay){
//                                cal.add(Calendar.MONTH, -1);
//                            }
//                            Date transDate=cal.getTime();
//                            String tmp=sdf.format(transDate);
//                            String windDateTime=windInfoTime+tmp.substring(2);
//                            Date validWindTime=DateUtil.StrToDateMonthAbb(windDateTime, SysConstants.FORMAT_DATETIME_ABBRE);
//                            //跨年跨月，风温数据时间应为上个月的数据
//                            planFlightInfoBuff.setPlanDate(validWindTime);
//                            bPlanTime = true;
//                        }
                    }
                    if (null == planFlightInfoBuff.getPlanID()) {
                        if (matcher1.group(7).trim().equals("")) {
                            logger.error("飞行计划ID为空字符串！");
                        }
                        else {
                            planFlightInfoBuff.setPlanID(matcher1.group(7).trim());
                            bPlanTime = true;
                        }
                    }
                }
                // 整个飞行计划遍历一遍，没有匹配到某项非空信息后，飞行计划解析失败
                if(!bFind){
                    logger.error("航空公司三字码在配置文件中不存在！");
                    return false;
                }
                else if (!bFlightnumDepArr) {
                    logger.error("航班航、起飞机场、落地机场匹配失败！");
                    return false;
                } else if (!bAircraftid) {
                    logger.error("机尾号匹配失败！");
                    return false;
                } else if (!bPlanTime) {
                    logger.error("飞行计划时间匹配失败！");
                    return false;
                }
            }
            //预计起飞时间和预计到达时间
            if(!baseInfos[1].equals(""))
            {
                String deptime=baseInfos[1].trim();
                planFlightInfoBuff.setDeptime(deptime.substring(0,4));
            }
            /*
               第二部分匹配航路点及其经纬度然后存入HashMap和cptInfoList，第三部分匹配航路点，及其对应高度层的风温信息，
                匹配时从HashMap中选出经纬度然后存入planCptWdList
             */
            for(int i=2;i<cptLonLatInfos.length-2;i++){

                String[] temps=cptLonLatInfos[i].split("\r\n");
                ArrayList<String> temp2= new ArrayList<String>();
                //过滤掉空格开头或者空字符开头的行
                if(temps.length>3){
                    for(int j=0;j<temps.length;j++){
                        if(!temps[j].startsWith("")||(!temps[j].startsWith(" "))){
                            temp2.add(temps[j]);
                        }
                    }
                    if(temp2.size()>=2){
                        matcher2 = pattern2.matcher(temp2.get(temp2.size()-2).toString());
                        matcher3 =pattern3.matcher(temp2.get(temp2.size()-1).toString());
                    }
                }
                else{
                    matcher2 = pattern2.matcher(temps[temps.length-2].toString());
                    matcher3 =pattern3.matcher(temps[temps.length-1].toString());
                }

                //在一个航路点信息内匹配航路点和经纬度
                boolean cptmatch=matcher2.matches();
                boolean latlonmatch=matcher3.matches();
//                String fl=matcher3.group(1);
//                System.out.println("group  "+matcher3.group(1)+","
//                                +matcher3.group(2)+","
//                                +matcher3.group(3)+","
//                                +matcher3.group(4)+","
//
//                );
                if(matcher2.matches()&&matcher3.matches()){
                    String cpt=matcher2.group(2).trim();
                    String lat=matcher3.group(2)+matcher3.group(3);
                    String lon=matcher3.group(4)+matcher3.group(5);
                    lat=lat.replace(" ","").replace(".","");
                    lon=lon.replace(" ","").replace(".","");
                    //如果某航路点经纬度不符合规定则舍弃
                    if (cpt.equals("") || !ValidCheckAviation.RegexCheck(lat, ValidCheckAviation.CheckType.WindLat.ordinal())
                            || !ValidCheckAviation.RegexCheck(lon, ValidCheckAviation.CheckType.WindLon.ordinal())) {
                        logger.error("航路点: "+cpt+", 经纬度，Lat: "+lat+", lon"+lon+" 格式不符合规定");
                        continue;
                    }
                    cptLon.put(cpt,lon);
                    cptLat.put(cpt,lat);
                }
            }
            String[] header=null;
            ArrayList<String> fixedLevel=new ArrayList<String>();
            try{
                header=cptLevelWindInfos[1].split(" ");
            }
            catch(Exception e){
                logger.error("解析航路风温摘要头信息失败：原信息："+cptLevelWindInfos[1]);
                return false;

            }

            int flNum=0;
            for(int i=1;i<header.length;i++){
                header[i]=header[i].trim();
                if(header[i].startsWith("FL")){
                    if(header[i].length()>2){
                        fixedLevel.add(header[i].substring(2)+"00");
                    }
                    else{
                        flNum++;
                    }
                }
            }


            for(int i=2;i<cptLevelWindInfos.length;i++){
                try{
                    if(!cptLevelWindInfos[i].equals("")&&!cptLevelWindInfos[i].startsWith(" ")&&!cptLevelWindInfos[i].startsWith("DESCENT")&&!cptLevelWindInfos[i].startsWith("\f")){
                        CptInfo cptInfo = new CptInfo();
                        String point=cptLevelWindInfos[i].substring(0,5).trim();
                        cptInfo.setCptName(point);
                        cptInfo.setLat(cptLat.get(point).toString());
                        cptInfo.setLon(cptLon.get(point).toString());
                        cptInfo.setFlightId(planFlightInfoBuff.getFlightId());
                        cptInfo.setAircraftId(planFlightInfoBuff.getAircraftId());
                        cptInfo.setAirlines(planFlightInfoBuff.getAirlines());
                        cptInfo.setArr(planFlightInfoBuff.getArr());
                        cptInfo.setDep(planFlightInfoBuff.getDep());
                        cptInfo.setPlanDate(planFlightInfoBuff.getPlanDate());
                        cptInfo.setPlanId(planFlightInfoBuff.getPlanID());

                        cptInfoList.add(cptInfo);
                        String[] singleLine=cptLevelWindInfos[i].substring(7).split(" ");

             /*
             第三部分匹配航路点，及其对应高度层的风温信息，匹配时从HashMap中选出经纬度然后存入planCptWdList
             */
                        //录入固定高度层的风温数据
                        for(int j=0;j<fixedLevel.size();j++){
                            PlanCptWd planCptWd=new PlanCptWd();
                            planCptWd.setAlt(Integer.parseInt(fixedLevel.get(j)));
                            String windInfo=singleLine[j].trim();
                            if (!ValidCheckAviation.RegexCheck(windInfo.substring(0, 3), ValidCheckAviation.CheckType.WindDir.ordinal(), "\\d{3}")
                                    || !ValidCheckAviation.RegexCheck(windInfo.substring(3, 6), ValidCheckAviation.CheckType.WindVel.ordinal())
                                    )
                            {
                                logger.error("本高度层："+fixedLevel.get(j)+", 航路点风速: "+windInfo.substring(0,3)+", 风向:"+""+windInfo.substring(3, 6)+"不合法");
                                continue;
                            }
                            else{
                                planCptWd.setWindDir(Integer.parseInt(windInfo.substring(0,3)));
                                planCptWd.setWindVel(Integer.parseInt(windInfo.substring(3,6)));
                            }
                            if(windInfo.substring(6).startsWith("M")){
                                planCptWd.setWindTep(Integer.parseInt("-" + windInfo.substring(7)));
                            }
                            else{
                                planCptWd.setWindTep(Integer.parseInt(windInfo.substring(7)));
                            }
                            planCptWd.setCptName(point);
                            planCptWd.setFlightId(planFlightInfoBuff.getFlightId());
                            planCptWd.setPlanDate(planFlightInfoBuff.getPlanDate());
                            planCptWd.setAircraftId(planFlightInfoBuff.getAircraftId());
                            planCptWd.setAirlines(planFlightInfoBuff.getAirlines());
                            planCptWd.setPlanId(planFlightInfoBuff.getPlanID());
                            planCptWdList.add(planCptWd);
                        }
                        //录入浮动高度层的风温数据
                        for(int j=0;j<flNum;j++){
                            PlanCptWd planCptWd=new PlanCptWd();
                            String level=singleLine[fixedLevel.size()+2*j];
                            if(level.length()==2){
                                planCptWd.setAlt(Integer.parseInt(singleLine[fixedLevel.size()+2*j].trim()+"000"));
                            }
                            else{
                                planCptWd.setAlt(Integer.parseInt(singleLine[fixedLevel.size()+2*j].trim()+"00"));
                            }
                            planCptWd.setAlt(Integer.parseInt(singleLine[fixedLevel.size()+2*j].trim()+"00"));
                            String windInfo=singleLine[fixedLevel.size()+2*j+1].trim();
                            if (!ValidCheckAviation.RegexCheck(windInfo.substring(0, 3), ValidCheckAviation.CheckType.WindDir.ordinal(), "\\d{3}")
                                    || !ValidCheckAviation.RegexCheck(windInfo.substring(3, 6), ValidCheckAviation.CheckType.WindVel.ordinal())
                                    )
                            {
                                logger.error("本高度层："+planCptWd.getAlt()+", 航路点风速: "+windInfo.substring(0,3)+", 风向:"+""+windInfo.substring(3, 6)+"不合法");
                                continue;
                            }
                            else{
                                planCptWd.setWindDir(Integer.parseInt(windInfo.substring(0,3)));
                                planCptWd.setWindVel(Integer.parseInt(windInfo.substring(3,6)));
                            }
                            if(windInfo.substring(6).startsWith("M")){
                                planCptWd.setWindTep(Integer.parseInt("-" + windInfo.substring(7)));
                            }
                            else{
                                planCptWd.setWindTep(Integer.parseInt(windInfo.substring(7)));
                            }
                            planCptWd.setCptName(point);
                            planCptWd.setFlightId(planFlightInfoBuff.getFlightId());
                            planCptWd.setPlanDate(planFlightInfoBuff.getPlanDate());
                            planCptWd.setAircraftId(planFlightInfoBuff.getAircraftId());
                            planCptWd.setAirlines(planFlightInfoBuff.getAirlines());
                            planCptWd.setPlanId(planFlightInfoBuff.getPlanID());
                            planCptWdList.add(planCptWd);
                        }
                    }
                }
                catch(Exception e){
                    logger.error("cptLevelWindInfo" + i + ":" + cptLevelWindInfos[i]);
                    logger.error("cpt level wind parse exception: "+e.toString());
                }

            }
//            routeLine=routeLine.substring(0,routeLine.length()-1)+"-"+planFlightInfoBuff.getArr();
            String routeline="";
            for(int i=0;i<routeLine.length;i++){
                //这个元素是起飞机场或者是目的机场
                if(i==0||i==(routeLine.length-1)){
                    routeline=routeline+routeLine[i].trim();
                }
                //这个元素既不是起飞机场也是不是目的机场，而是一个航路或者航路点
                else {
                    //直飞
                    if(routeLine[i].contains("DCT")){
                        routeline=routeline+"-";
                    }
                    //这是一个航路点
                    else if(cptLon.containsKey(routeLine[i])){
                        String latlon=routeLine[i];
                        //这是一个经纬度航路点的简写
                        if(Character.isDigit(latlon.charAt(1))){
                            latlon=cptLat.get(latlon).toString()+cptLon.get(latlon).toString();
                        }
                        if(routeline.endsWith("/")||routeline.endsWith("-")){
                            routeline=routeline+latlon;
                        }
                        else{
                            routeline=routeline+"-"+latlon;
                        }
                    }
                    //这不是一个航路点而是一个航路或者是一个进场程序
                    else{
                        //在到达目的机场前的最后一个点不能是航路
                        if(i!=routeLine.length-2){
                            //如果这是一个灵活航路点
                            if(routeLine[i].startsWith("FLX")){
                                //找到前后的航路点
                                String startCpt=routeLine[i-1];
                                String endCpt=routeLine[i+1];
                                boolean weiter=false;
                                //对planCptWdList进行遍历
                                for(int j=0;j<cptInfoList.size();j++){

                                    String tmp=((CptInfo)cptInfoList.get(j)).getCptName();
                                    if(tmp.equals(startCpt)){
                                        weiter=true;
                                    }
                                    if(tmp.equals(endCpt)){
                                        break;
                                    }
                                    if(weiter&&(!tmp.startsWith("EEP"))&&(!tmp.startsWith("ETP"))&&(!tmp.startsWith("EXP"))
                                            &&(!tmp.startsWith(startCpt))&&(!tmp.startsWith(endCpt))){
                                        String flxCpt=tmp;
                                        if(Character.isDigit(tmp.charAt(1))){
                                            flxCpt=cptLat.get(tmp).toString()+cptLon.get(tmp).toString();
                                        }
                                        routeline=routeline+"-"+flxCpt;
                                    }
                                    else{
                                        continue;
                                    }
                                }
                            }
                            else{
                                routeline=routeline+"/"+routeLine[i]+"/";
                            }
                        }
                        //这是一个进场程序，暂时以DCT（直飞）替代
                        else{
                            routeline=routeline+"-";
                        }
                    }
                }
            }
            cptSend = new CptSend();
            cptSend.setRouteline(routeline);
            cptSend.setArr(planFlightInfoBuff.getArr());
            cptSend.setDep(planFlightInfoBuff.getDep());
            cptSend.setAirlines(planFlightInfoBuff.getAirlines());
            cptSend.setFlightId(planFlightInfoBuff.getAirlines() + planFlightInfoBuff.getFlightId());
            cptSend.setAircraftId(planFlightInfoBuff.getAircraftId());
            cptSend.setPlanId(planFlightInfoBuff.getPlanID());
            cptSend.setPlanDate(planFlightInfoBuff.getPlanDate());
            String deptime="";
            //如果文件名中包含预计起飞日期
            if(fileName.contains("Dep")){
                int indexDep=fileName.indexOf("Dep");
                depDate=fileName.substring(indexDep + 3, indexDep + 11);
                deptime=depDate+planFlightInfoBuff.getDeptime();
            }
            else{
                deptime=sdf2.format(planFlightInfoBuff.getPlanDate())+planFlightInfoBuff.getDeptime();
            }
            cptSend.setDepdate(sdf.parse(deptime));
            cptSend.setSendType("2");
            cptSend.setSendStatus("2");
            cptSend.setCaptainStatus("0");

        }
        catch (Exception e) {
            logger.error("SABREF TXT格式飞行计划解析异常:" + e.toString());
            return false;
        }
        return true;
    }

    @Override
    public void saveToDB() {
        try {
            // CPT_INFO 数据入库
            cptInfoService.saveOrUpdate(cptInfoList);
            // PLAN_CPT_WD 数据入库
            planCptWdService.save(planCptWdList);
            //CPT_SEND数据入库
            cptSendService.saveOrUpdate(cptSend);
        } catch (Exception e) {
            logger.error("数据库访问异常：" + e.getMessage());
        }
    }


    public static void main(String[] args){

        SABREFlyPlanParseController sabreFlyPlanParseController=new SABREFlyPlanParseController("");
        File file = new File("F:/FML/FlyPlanData/MU_MU2856_FlightPlanContent2016061711131.M00");
        StringBuilder sb = new StringBuilder();
        try{
            String s ="";
            BufferedReader br = new BufferedReader(new FileReader(file));

            while( (s = br.readLine()) != null) {
                sb.append(s + "\r\n");
            }
            br.close();
        }
        catch(Exception e){

        }
        String str = sb.toString();
        sabreFlyPlanParseController.parseDataSource(str);
    }
}
